package com.jiazhong.example.project.bookstore.front.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.jiazhong.example.project.bookstore.commons.bean.Alipay;
import com.jiazhong.example.project.bookstore.commons.bean.Order;
import com.jiazhong.example.project.bookstore.commons.bean.OrderItem;
import com.jiazhong.example.project.bookstore.commons.bean.RocketMQOrder;
import com.jiazhong.example.project.bookstore.commons.mapper.OrderItemMapper;
import com.jiazhong.example.project.bookstore.commons.util.JsonResult;
import com.jiazhong.example.project.bookstore.commons.util.ResultTool;
import com.jiazhong.example.project.bookstore.front.service.AlipayService;
import com.jiazhong.example.project.bookstore.front.service.OrderService;
import jakarta.annotation.Resource;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.client.producer.TransactionSendResult;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
public class AlipayServiceImpl implements AlipayService {

    @Value("${appId}")
    private String appId;
    @Value("${privateKey}")
    private String privateKey;
    @Value("${publicKey}")
    private String publicKey;
    @Value("${notifyUrl}")
    private String notifyUrl;
    @Value("${returnUrl}")
    private String returnUrl;
    @Value("${signType}")
    private String signType;
    @Value("${charset}")
    private String charset;
    @Value("${gatewayUrl}")
    private String gatewayUrl;
    @Resource
    private OrderService orderService;
    @Resource
    private RocketMQTemplate rocketMQTemplate;
    @Resource
    private OrderItemMapper orderItemMapper;

    @SneakyThrows
    @Override
    public String pay(Alipay alipay, String logisticsId) {
        log.info("开始执行支付操作：{}", alipay);
        // 产生支付宝的客户端
        AlipayClient client = new DefaultAlipayClient(gatewayUrl, appId, privateKey,
                "json", charset, publicKey, signType);
        // 产生交易对象
        AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
        // 设置回调
        request.setReturnUrl(returnUrl);
        request.setNotifyUrl(notifyUrl);
        // 设置支付参数
        String s = JSONArray.toJSONString(alipay);
        request.setBizContent(s);
        // 执行
        String body = client.pageExecute(request).getBody();
        // 设置多长时间后去执行某段代码
        ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1);
        // 目前是1min，其后我们会改成10min
        scheduledExecutorService.schedule(() -> {
            query(alipay.getOut_trade_no(), logisticsId);
        }, 2, TimeUnit.MINUTES);
        /*scheduledExecutorService.scheduleAtFixedRate(() -> {
            query(alipay.getOut_trade_no(), logisticsId);
        }, 10, 5, TimeUnit.SECONDS);*/
        return body;
    }

    @SneakyThrows
    public JsonResult query(String orderId, String logisticsId) {
        log.info("开始查询用户是否付款");
        AlipayClient client = new DefaultAlipayClient(gatewayUrl, appId, privateKey,
                "json", charset, publicKey, signType);
        AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
        Alipay alipay = new Alipay();
        alipay.setOut_trade_no(orderId);
        request.setBizContent(JSONArray.toJSONString(alipay));
        AlipayTradeQueryResponse response = client.execute(request);
        // TRADE_SUCCESS  WAIT_BUYER_PAY   null
        String tradeStatus = response.getTradeStatus();
        switch (tradeStatus) {
            case "TRADE_SUCCESS" -> {
                log.info("用户成功付款了");
                // 1. 判断状态是否修改了
                Order order = orderService.getById(orderId);
                log.info("用户的订单信息：{}", order);
                if (order.getStatus() == 1) {
                    log.info("开始修改状态以及发送消息");
                    // 2.1 修改status
                    UpdateWrapper<Order> updateWrapper = new UpdateWrapper<>();
                    updateWrapper.eq("id", orderId);
                    updateWrapper.eq("status", 1);
                    updateWrapper.set("status", 2);
                    orderService.update(updateWrapper);
                    // 2.2 向rocketMQ发送一笔半事务消息
                    // 图书ID、扣减的数量、订单ID，物流收货人姓名、电话以及地址
                    // 2.3 获取到订单详情信息
                    QueryWrapper<OrderItem> queryWrapper = new QueryWrapper<>();
                    queryWrapper.eq("order_id", orderId);
                    List<OrderItem> orderItems = orderItemMapper.selectList(queryWrapper);
                    RocketMQOrder rocketMQOrder = new RocketMQOrder();
                    rocketMQOrder.setOrderId(orderId);
                    rocketMQOrder.setUserId(order.getUserId());
                    rocketMQOrder.setLogisticsId(logisticsId);
                    rocketMQOrder.setOrderItemList(orderItems);
                    rocketMQOrder.setTotalPrice(alipay.getTotal_amount());
                    rocketMQOrder.setAlipayClient(client);
                    String body = JSONArray.toJSONString(rocketMQOrder);
                    Message<String> message = MessageBuilder.withPayload(body).build();
                    TransactionSendResult sendResult = rocketMQTemplate.sendMessageInTransaction("order01", "Order:transaction", message, body);
                    log.info("sendResult:{}", sendResult);
                }
            }
        }
        log.info("tradeStatus:{}", tradeStatus);
        return ResultTool.success("success");
    }
}
